home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_08 / beddow / transact.c < prev   
Encoding:
C/C++ Source or Header  |  1995-02-04  |  7.3 KB  |  216 lines

  1. /* ******************************************************************* */
  2. /* Transaction Management Functions                       */
  3.  
  4. /* ****************************** */
  5. /* Open a network client (master) 
  6.    Sets up the global masterid as the client name id. Note only
  7.    one client per machine */
  8. open_net_client(char *name) 
  9. {  struct Ncb command_ncb ;
  10.    int dgstat = -1 ;
  11.    
  12.    if (chk_net_bios())
  13.      { printf("%s", errmes1) ;
  14.        exit(1) ;
  15.      }
  16.    if (masterid == -1)
  17.     { NetDelName(name, command_ncb) ;  // Precaution against a lost name
  18.       strcpy(mastername, name) ;   
  19.       if ((dgstat = NetAddName(mastername,command_ncb)) == 0)
  20.         masterid = command_ncb.NCB_num ;
  21.     }
  22.    return(dgstat) ;
  23. }
  24.  
  25. /* ***********************  */
  26. /* Close the network client */
  27. close_net_client(void)
  28. { struct Ncb command_ncb ;
  29.   int dgstat ;
  30.   
  31.   dgstat = NetDelName(mastername, command_ncb) ;
  32.   masterid = -1 ;
  33.   return(dgstat) ;
  34. }
  35.  
  36. /* *********************************************************************** */
  37. /* Install a datagram server on a given local name. Slave will call post
  38.    function given when a transaction occurs. Slave will return 0 to master
  39.    if post function was successful or error code if not.
  40.    The Net name descriptor is entered in a linked list.
  41.    Return pointer to descriptor if successful                              */ 
  42. struct netrpcserver *install_rpcserver(char *name, void *(*rpc)(void *),
  43.                                      int replysize)
  44. {  struct netrpcserver *ep ;
  45.    int dgstat = 0 ;
  46.    void netslavepost(struct Ncb far *) ;
  47.  
  48. /* Check for Net Bios first */
  49.    if (chk_net_bios())
  50.      { printf("%s", errmes1) ;
  51.        exit(1) ;
  52.      }
  53.    
  54. /* Malloc descriptor space */
  55.     if ((ep = (struct netrpcserver *)malloc(sizeof(struct netrpcserver))) == NULL)
  56.       return(NULL) ;
  57.     if ((ep->name = strdup(name)) == NULL)
  58.       { free(ep) ;
  59.         return(NULL) ;
  60.       }
  61. /* Clear error count and last_dgstat */
  62.    ep->errcnt = 0 ;
  63.    ep->errcnt = 0 ;
  64. /* Set up Remote procedure call and replysize */
  65.     ep->rpc = rpc ;
  66.     if (replysize < DGRAMSIZE)
  67.       ep->replysize = replysize ;
  68.     else
  69.       ep->replysize = DGRAMSIZE ;
  70. /* Malloc space for Ncb's */
  71.     if ((ep->receivencbptr = (struct Ncb *)calloc(2,sizeof(struct Ncb))) == NULL)
  72.       { free(ep->name) ;
  73.         free(ep) ;
  74.         return(NULL) ; 
  75.       }
  76.     ep->sendncbptr = ep->receivencbptr + 1 ;
  77. /* Malloc space for Datagram buffer */
  78.     if ((ep->dgbufin = (char *)malloc(DGRAMSIZE)) == NULL)
  79.       { free(ep->name) ;
  80.         free(ep) ;
  81.         return(NULL) ; 
  82.       }
  83. /* Install name */
  84.     NetDelName_p(name, ep->receivencbptr) ;
  85.     if ((dgstat = net_name_command(NCBADDNAME,name,NULL,ep->receivencbptr)) != 0)
  86.       { free(ep->dgbufin) ;
  87.         free(ep->receivencbptr) ;
  88.         free(ep->name) ;
  89.         free(ep) ;
  90.         return(NULL) ; 
  91.       }
  92. /* Set up name id */
  93.    ep->id = ep->receivencbptr->NCB_num ;
  94. /* and link in */
  95.    if (netrpcserverlist == NULL)
  96.      { netrpcserverlist = ep ;
  97.        ep->prev = NULL ;
  98.      }
  99.    else
  100.      { ep->prev = netrpcserverlist ;
  101.        netrpcserverlist = ep ;
  102.      }
  103.  
  104. /* Now set up receive */
  105.    if ( dgstat |= net_dgram_command(NCBRECEIVEDATAGRAM | NCBNO_WAIT,ep->id,NULL,ep->dgbufin,
  106.                                      sizeof(struct dgbufsize),NULL,ep->receivencbptr))               
  107.      { net_name_command(NCBDELETENAME,name,NULL,ep->receivencbptr) ;
  108.        free(ep->dgbufin) ;
  109.        free(ep->receivencbptr) ;
  110.        free(ep->name) ;
  111.        free(ep) ;
  112.        return(NULL) ; 
  113.      }
  114.    else
  115.      return(ep) ;
  116. }
  117.  
  118. /* ****************************************************************** */ 
  119. /* Remove all net names and pending receives  for all datagram servers */
  120. void remove_all_rpcservers(void) 
  121. { char *ptr ;
  122.   struct Ncb command_ncb ;
  123.   
  124.   if (netrpcserverlist != NULL)
  125.     { do
  126.        { 
  127.          net_command_cancel(netrpcserverlist->receivencbptr,&command_ncb) ;
  128.          NetDelName(netrpcserverlist->name, command_ncb) ;
  129.          if (netrpcserverlist->errcnt)
  130.           { printf("%d errors occured on rpcserver %s\n", netrpcserverlist->errcnt,
  131.                     netrpcserverlist->name) ;
  132.             printf("Last error was %s\n",
  133.                     get_neterrmess(netrpcserverlist->last_dgstat)) ;
  134.           }        
  135.          free(netrpcserverlist->dgbufin) ;
  136.          free(netrpcserverlist->receivencbptr) ;
  137.          free(netrpcserverlist->name) ;
  138.          ptr = (char *) netrpcserverlist ;
  139.          netrpcserverlist = netrpcserverlist->prev ;
  140.          free(ptr) ;
  141.        }
  142.       while (netrpcserverlist != NULL) ;
  143.     }
  144. }
  145.  
  146.  
  147. /* ******************************************************************* */
  148. /* Transact a message 
  149.    Uses global masterid as sender id. This must have been set up first
  150.    by open_net_client().
  151.    Note : I would advise the implementation of interrupt driven timeout capability and locking
  152.    against re-entrance for multi-threaded applications.
  153. */
  154.  
  155. net_transact(char *name, void *bufin, int bufinlen,
  156.             void *bufout, int bufoutlen)
  157.   struct Ncb send_ncb, receive_ncb, command_ncb ;
  158.   char remotename[17] ;
  159.   int dgstat = 0 ;
  160.   long count = 0 ;
  161.  
  162.   dgstat |= net_dgram_command(NCBRECEIVEDATAGRAM | NCBNO_WAIT, masterid, NULL,
  163.                             bufin, bufinlen, NULL, &receive_ncb) ;
  164.   dgstat |= net_dgram_command(NCBSENDDATAGRAM, masterid, name, bufout, bufoutlen ,NULL,
  165.                             &send_ncb) ;
  166.  
  167.   while(receive_ncb.NCB_cmd_cplt == 0xff)
  168.      { count++ ;
  169.        if (count > 100000)
  170.         { dgstat = NETTIMEOUTERR ; 
  171.           net_command_cancel(&receive_ncb,&command_ncb) ;
  172.           break ;
  173.         }
  174.      }
  175.  
  176.   return(dgstat) ;
  177. }
  178.  
  179. /* ****************************************************************** */
  180. /* net_comms(). This is the datagram server function that
  181.    services transaction requests. It must be called regularly to service
  182.    all received transaction requests                                    */
  183. void net_comms()
  184. { struct netrpcserver *netrpcserverptr ;
  185.   char netmaster[17] ;
  186.   void *replyptr ;
  187.   int dgstat = 0 ;
  188.  
  189. /* Track list serving any pending datagrams by calling the server funtion
  190.    with a void pointer to the datagram.
  191.    The server function will return a pointer to its reply message which is
  192.    returned to the transaction master.
  193. */
  194.   netrpcserverptr = netrpcserverlist ;
  195.   while(netrpcserverptr != NULL)
  196.    { if (netrpcserverptr->receivencbptr->NCB_cmd_cplt != 0xff)
  197.       { dgstat |= netrpcserverptr->receivencbptr->NCB_cmd_cplt ; 
  198.         ret_ncb_callname(netmaster, netrpcserverptr->receivencbptr) ;
  199.         replyptr = (*netrpcserverptr->rpc)(netrpcserverptr->dgbufin) ;
  200.         dgstat |= net_dgram_command(NCBRECEIVEDATAGRAM | NCBNO_WAIT,netrpcserverptr->id,
  201.                                     NULL,netrpcserverptr->dgbufin,sizeof(struct dgbufsize),
  202.                                     NULL,netrpcserverptr->receivencbptr) ;
  203.         dgstat |= net_dgram_command(NCBSENDDATAGRAM,netrpcserverptr->id, netmaster,
  204.                   replyptr, netrpcserverptr->replysize, NULL,
  205.                   netrpcserverptr->sendncbptr) ;
  206.         if (dgstat)
  207.          { netrpcserverptr->errcnt++ ;
  208.            netrpcserverptr->last_dgstat = dgstat ;
  209.          }
  210.        }
  211.      netrpcserverptr = netrpcserverptr->prev ;
  212.    } 
  213. }
  214.  
  215.